/**
 * 图片缓存管理模块
 * 处理图片预加载、缓存、懒加载等功能
 */

window.ComicReader = window.ComicReader || {};

ComicReader.ImageCache = class {
    constructor(options = {}) {
        this.options = {
            maxCacheSize: 100,           // 最大缓存图片数量
            preloadDistance: 2,          // 预加载距离（前后页数）
            retryAttempts: 3,            // 重试次数
            retryDelay: 1000,            // 重试延迟
            quality: 85,                 // 默认图片质量
            enableServiceWorker: false,  // 是否启用Service Worker
            ...options
        };
        
        this.cache = new Map();          // 图片缓存
        this.loading = new Set();        // 正在加载的图片
        this.preloading = new Set();     // 正在预加载的图片
        this.loadQueue = [];             // 加载队列
        this.isProcessingQueue = false;  // 是否正在处理队列
        
        this.stats = {
            hit: 0,                      // 缓存命中次数
            miss: 0,                     // 缓存未命中次数
            loaded: 0,                   // 成功加载次数
            failed: 0                    // 加载失败次数
        };
        
        this.init();
    }
    
    init() {
        // 监听内存警告
        if ('memory' in performance && 'onmemorywarning' in window) {
            window.addEventListener('memorywarning', () => {
                this.cleanup();
            });
        }
        
        // 监听页面可见性变化
        document.addEventListener('visibilitychange', () => {
            if (document.hidden) {
                this.pausePreloading();
            } else {
                this.resumePreloading();
            }
        });
        
        // 网络状态监听
        if ('connection' in navigator) {
            navigator.connection.addEventListener('change', () => {
                this.adaptToNetworkCondition();
            });
        }
    }
    
    /**
     * 获取图片URL（带缓存参数）
     */
    getImageUrl(imagePath, quality = null) {
        const baseUrl = `/api/image/${encodeURIComponent(imagePath)}`;
        const params = new URLSearchParams();
        
        if (quality || this.options.quality) {
            params.append('quality', quality || this.options.quality);
        }
        
        return params.toString() ? `${baseUrl}?${params}` : baseUrl;
    }
    
    /**
     * 获取缩略图URL
     */
    getThumbnailUrl(imagePath, width = 300, height = 400) {
        const baseUrl = `/api/thumbnail/${encodeURIComponent(imagePath)}`;
        return `${baseUrl}?width=${width}&height=${height}`;
    }
    
    /**
     * 加载图片
     */
    async loadImage(src, priority = 'normal') {
        // 检查缓存
        if (this.cache.has(src)) {
            this.stats.hit++;
            return this.cache.get(src);
        }
        
        this.stats.miss++;
        
        // 检查是否正在加载
        if (this.loading.has(src)) {
            return this.waitForLoad(src);
        }
        
        // 添加到加载队列
        return new Promise((resolve, reject) => {
            this.loadQueue.push({
                src,
                priority,
                resolve,
                reject,
                attempts: 0
            });
            
            this.processQueue();
        });
    }
    
    /**
     * 处理加载队列
     */
    async processQueue() {
        if (this.isProcessingQueue || this.loadQueue.length === 0) return;
        
        this.isProcessingQueue = true;
        
        // 按优先级排序
        this.loadQueue.sort((a, b) => {
            const priorities = { high: 3, normal: 2, low: 1 };
            return (priorities[b.priority] || 2) - (priorities[a.priority] || 2);
        });
        
        while (this.loadQueue.length > 0) {
            const task = this.loadQueue.shift();
            
            try {
                const image = await this.doLoadImage(task.src);
                task.resolve(image);
            } catch (error) {
                task.attempts++;
                
                if (task.attempts < this.options.retryAttempts) {
                    // 重试
                    await this.delay(this.options.retryDelay * task.attempts);
                    this.loadQueue.unshift(task);
                } else {
                    task.reject(error);
                }
            }
        }
        
        this.isProcessingQueue = false;
    }
    
    /**
     * 实际加载图片
     */
    async doLoadImage(src) {
        if (this.loading.has(src)) {
            return this.waitForLoad(src);
        }
        
        this.loading.add(src);
        
        try {
            const image = await this.createImage(src);
            
            // 添加到缓存
            this.addToCache(src, image);
            this.stats.loaded++;
            
            return image;
        } catch (error) {
            this.stats.failed++;
            throw error;
        } finally {
            this.loading.delete(src);
        }
    }
    
    /**
     * 创建图片对象
     */
    createImage(src) {
        return new Promise((resolve, reject) => {
            const img = new Image();
            
            img.onload = () => resolve(img);
            img.onerror = () => reject(new Error(`图片加载失败: ${src}`));
            
            // 设置跨域
            img.crossOrigin = 'anonymous';
            img.src = src;
        });
    }
    
    /**
     * 等待图片加载完成
     */
    async waitForLoad(src) {
        while (this.loading.has(src)) {
            await this.delay(50);
        }
        
        if (this.cache.has(src)) {
            return this.cache.get(src);
        }
        
        throw new Error(`图片加载失败: ${src}`);
    }
    
    /**
     * 添加到缓存
     */
    addToCache(src, image) {
        // 检查缓存大小限制
        if (this.cache.size >= this.options.maxCacheSize) {
            this.cleanup();
        }
        
        // 添加时间戳和访问计数
        const cacheItem = {
            image,
            timestamp: Date.now(),
            accessCount: 1,
            lastAccess: Date.now()
        };
        
        this.cache.set(src, cacheItem);
    }
    
    /**
     * 从缓存获取图片
     */
    getFromCache(src) {
        const item = this.cache.get(src);
        if (item) {
            item.accessCount++;
            item.lastAccess = Date.now();
            return item.image;
        }
        return null;
    }
    
    /**
     * 预加载图片列表
     */
    async preloadImages(srcList, priority = 'low') {
        const promises = srcList.map(src => {
            if (!this.cache.has(src) && !this.preloading.has(src)) {
                this.preloading.add(src);
                return this.loadImage(src, priority).finally(() => {
                    this.preloading.delete(src);
                });
            }
            return Promise.resolve();
        });
        
        try {
            await Promise.allSettled(promises);
        } catch (error) {
            console.warn('预加载部分失败:', error);
        }
    }
    
    /**
     * 预加载章节页面
     */
    async preloadChapter(chapterId, startPage = 1, pageCount = null) {
        try {
            const response = await fetch(`/api/chapters/${chapterId}/pages`);
            const data = await response.json();
            
            if (data.status === 'success') {
                const pages = data.data.pages;
                const endPage = pageCount ? Math.min(startPage + pageCount - 1, pages.length) : pages.length;
                
                const srcList = [];
                for (let i = startPage - 1; i < endPage; i++) {
                    if (pages[i]) {
                        srcList.push(this.getImageUrl(pages[i].image_path));
                    }
                }
                
                await this.preloadImages(srcList, 'low');
                
                return {
                    preloaded: srcList.length,
                    total: pages.length
                };
            }
        } catch (error) {
            console.error('预加载章节失败:', error);
            throw error;
        }
    }
    
    /**
     * 智能预加载（根据当前阅读位置）
     */
    async smartPreload(comicId, chapterId, currentPage, chapters = []) {
        const tasks = [];
        
        // 预加载当前章节的相邻页面
        tasks.push(this.preloadAdjacentPages(chapterId, currentPage));
        
        // 预加载下一章节的前几页
        const currentChapterIndex = chapters.findIndex(ch => ch.id === chapterId);
        if (currentChapterIndex >= 0 && currentChapterIndex < chapters.length - 1) {
            const nextChapter = chapters[currentChapterIndex + 1];
            tasks.push(this.preloadChapter(nextChapter.id, 1, 3));
        }
        
        try {
            await Promise.allSettled(tasks);
        } catch (error) {
            console.warn('智能预加载失败:', error);
        }
    }
    
    /**
     * 预加载相邻页面
     */
    async preloadAdjacentPages(chapterId, currentPage) {
        try {
            const response = await fetch(`/api/chapters/${chapterId}/pages`);
            const data = await response.json();
            
            if (data.status === 'success') {
                const pages = data.data.pages;
                const srcList = [];
                
                // 预加载前后指定距离的页面
                const start = Math.max(0, currentPage - 1 - this.options.preloadDistance);
                const end = Math.min(pages.length, currentPage - 1 + this.options.preloadDistance + 1);
                
                for (let i = start; i < end; i++) {
                    if (i !== currentPage - 1 && pages[i]) {
                        srcList.push(this.getImageUrl(pages[i].image_path));
                    }
                }
                
                await this.preloadImages(srcList, 'normal');
            }
        } catch (error) {
            console.error('预加载相邻页面失败:', error);
        }
    }
    
    /**
     * 清理缓存
     */
    cleanup() {
        const items = Array.from(this.cache.entries());
        
        // 按访问时间和频率排序，移除最不活跃的
        items.sort((a, b) => {
            const scoreA = a[1].accessCount * 0.7 + (Date.now() - a[1].lastAccess) * 0.3;
            const scoreB = b[1].accessCount * 0.7 + (Date.now() - b[1].lastAccess) * 0.3;
            return scoreB - scoreA;
        });
        
        // 移除一半缓存
        const removeCount = Math.floor(this.cache.size / 2);
        for (let i = 0; i < removeCount; i++) {
            this.cache.delete(items[i][0]);
        }
        
        console.log(`清理了 ${removeCount} 个缓存项`);
    }
    
    /**
     * 清空所有缓存
     */
    clear() {
        this.cache.clear();
        this.loading.clear();
        this.preloading.clear();
        this.loadQueue = [];
        this.stats = { hit: 0, miss: 0, loaded: 0, failed: 0 };
    }
    
    /**
     * 暂停预加载
     */
    pausePreloading() {
        this.loadQueue = this.loadQueue.filter(task => task.priority !== 'low');
    }
    
    /**
     * 恢复预加载
     */
    resumePreloading() {
        this.processQueue();
    }
    
    /**
     * 根据网络条件调整策略
     */
    adaptToNetworkCondition() {
        if ('connection' in navigator) {
            const connection = navigator.connection;
            
            if (connection.effectiveType === 'slow-2g' || connection.effectiveType === '2g') {
                // 慢网络：降低质量，减少预加载
                this.options.quality = 60;
                this.options.preloadDistance = 1;
            } else if (connection.effectiveType === '3g') {
                // 中等网络：标准设置
                this.options.quality = 75;
                this.options.preloadDistance = 2;
            } else {
                // 快网络：高质量，增加预加载
                this.options.quality = 85;
                this.options.preloadDistance = 3;
            }
        }
    }
    
    /**
     * 获取缓存统计
     */
    getStats() {
        const hitRate = this.stats.hit + this.stats.miss > 0 ? 
            (this.stats.hit / (this.stats.hit + this.stats.miss) * 100).toFixed(2) : '0.00';
        
        return {
            ...this.stats,
            hitRate: `${hitRate}%`,
            cacheSize: this.cache.size,
            maxCacheSize: this.options.maxCacheSize,
            loadingCount: this.loading.size,
            preloadingCount: this.preloading.size,
            queueLength: this.loadQueue.length
        };
    }
    
    /**
     * 延迟函数
     */
    delay(ms) {
        return new Promise(resolve => setTimeout(resolve, ms));
    }
}

// 懒加载组件
ComicReader.LazyLoad = class {
    constructor(options = {}) {
        this.options = {
            rootMargin: '100px',
            threshold: 0.1,
            ...options
        };
        
        this.observer = null;
        this.imageCache = options.imageCache || new ComicReader.ImageCache();
        
        this.init();
    }
    
    init() {
        if ('IntersectionObserver' in window) {
            this.observer = new IntersectionObserver(
                this.handleIntersection.bind(this),
                this.options
            );
        }
    }
    
    handleIntersection(entries) {
        entries.forEach(entry => {
            if (entry.isIntersecting) {
                this.loadImage(entry.target);
                this.observer.unobserve(entry.target);
            }
        });
    }
    
    async loadImage(img) {
        const src = img.dataset.src || img.src;
        if (!src) return;
        
        try {
            img.classList.add('loading');
            await this.imageCache.loadImage(src, 'high');
            img.src = src;
            img.classList.remove('loading');
            img.classList.add('loaded');
        } catch (error) {
            img.classList.remove('loading');
            img.classList.add('error');
            console.error('懒加载图片失败:', error);
        }
    }
    
    observe(img) {
        if (this.observer) {
            this.observer.observe(img);
        } else {
            // 降级处理：直接加载
            this.loadImage(img);
        }
    }
    
    unobserve(img) {
        if (this.observer) {
            this.observer.unobserve(img);
        }
    }
    
    disconnect() {
        if (this.observer) {
            this.observer.disconnect();
        }
    }
}

// 创建全局实例
ComicReader.imageCache = new ComicReader.ImageCache();
ComicReader.lazyLoad = new ComicReader.LazyLoad({
    imageCache: ComicReader.imageCache
});

// 工具函数
ComicReader.preloadImage = function(src, priority = 'normal') {
    return ComicReader.imageCache.loadImage(src, priority);
};

ComicReader.preloadImages = function(srcList, priority = 'low') {
    return ComicReader.imageCache.preloadImages(srcList, priority);
};

ComicReader.setupLazyLoad = function(container = document) {
    const images = container.querySelectorAll('img[data-src], img[loading="lazy"]');
    images.forEach(img => {
        ComicReader.lazyLoad.observe(img);
    });
};